package com.ctg.payroll2.service.sysadmin;

import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.Authentication;
import org.springframework.security.AuthenticationException;
import org.springframework.security.ui.webapp.AuthenticationProcessingFilter;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.ctg.payroll2.bean.po.SysUser;
import com.ctg.payroll2.util.Constants;
import com.ctg.platform.core.security.SpringSecurityManager;
import com.ctg.platform.core.security.Exception.ThreeTimesErrorException;
import com.ctg.platform.core.security.entity.Account;

public class BizAuthenticationProcessingFilter extends
		AuthenticationProcessingFilter {
	private Log logger = LogFactory.getLog(this.getClass());

	/**
	 * 取得service
	 * 
	 * @param servletContext
	 * @return
	 */
	protected SpringSecurityManager getSpringSecurityManager(
			ServletContext servletContext) {
		return (SpringSecurityManager) WebApplicationContextUtils
				.getWebApplicationContext(servletContext).getBean(
						"springSecurityManager");
	}

	/**
	 * 设置session
	 * 
	 * @param request
	 * @param userName
	 */
	private void setUserToSession(HttpServletRequest request, String userName) {
		SysUser user = new SysUser();
		SpringSecurityManager service = getSpringSecurityManager(request
				.getSession().getServletContext());
		Account a = service.getAccountByUserName(userName, null);// 得到账户信息
		LoginService loginService = (LoginService) WebApplicationContextUtils
				.getWebApplicationContext(
						request.getSession().getServletContext()).getBean(
						"loginService");
		String userId = a.getId();
		user = loginService.getCurrentUserByLoginName(userId, user);
		user.setLoginName(userName);
		user.setLoginId(StringUtils.upperCase(userName));
		user.setLoginIP(request.getRemoteAddr());

		user.setRoleList(service.getRoleListByLoginName(userName));

		request.getSession().setAttribute(Constants.CURRENT_USER, user);
		request.getSession().removeAttribute("rand");
		logger.debug("设置登录到session成功!");
	}

	@Override
	protected void onPreAuthentication(HttpServletRequest request,
			HttpServletResponse response) throws IOException {

		Integer times = (Integer) request.getSession().getAttribute(
				"ErrorTimes");
		if (times == null) {
			return;
		}
		if (times.intValue() >= Constants.USERNAME_OR_PASSWORD_ERROR_LIMIT) {
			try {
				throw new ThreeTimesErrorException("");
			} catch (RuntimeException e) {
				setCstomSwitch(true);
				setErrorMsg(Constants.THREETIME_ERROR_CODE,
						Constants.THREETIME_ERROR_MSG);
			}
		}
	}

	@Override
	protected void onSuccessfulAuthentication(HttpServletRequest request,
			HttpServletResponse response, Authentication authResult)
			throws IOException {
		String userName = request.getParameter("j_username");
		logger.debug("用户<" + userName + ">登录成功!");
		request.getSession().removeAttribute("ErrorTimes");
		setCstomSwitch(true);
		setErrorMsg(Constants.LOGIN_SUCCESS_CODE, null);
		setUserToSession(request, userName);
	}

	@Override
	protected void onUnsuccessfulAuthentication(HttpServletRequest request,
			HttpServletResponse response, AuthenticationException failed)
			throws IOException {
		String userName = (String) request.getAttribute("j_username");
		logger.debug("用户<" + userName + ">登录失败!");
		Integer times = (Integer) request.getSession().getAttribute(
				"ErrorTimes");
		if (times == null) {
			times = new Integer(0);
		}
		request.getSession().setAttribute("ErrorTimes", ++times);
		setCstomSwitch(true);
		if (times.intValue() >= Constants.USERNAME_OR_PASSWORD_ERROR_LIMIT) {
			setErrorMsg(Constants.THREETIME_ERROR_CODE,
					Constants.THREETIME_ERROR_MSG);
		} else {
			setErrorMsg(Constants.USERNAME_OR_PASSWORD_ERROR_CODE,
					Constants.USERNAME_OR_PASSWORD_ERROR_MSG);
		}
	}
}
